package org.linlinjava.litemall.wxserver.web;

import org.linlinjava.litemall.core.config.DesNoViUtil;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/wxs/voucher")
public class WxVoucherController {

    @Autowired
    private LitemallOrderVoucherService litemallOrderVoucherService;
    @Autowired
    private LitemallMechanismGoodsService mechanismGoodsService;

    @Autowired
    private PlatformTransactionManager txManager;

    @Autowired
    private LitemallUserService userService;

    @Autowired
    private  LitemallOrderService orderService;

    @Autowired
    private  LitemallWalletRecordService walletRecordService;

    @Autowired
    private  LitemallMechanismProductService productService;

    @Autowired
    private LitemallMechanismService mechanismService;

    /**
     * 代金券详情
     * @param id
     * @return
     */
    @GetMapping("/detail")
    public Object detail(Integer id){
        LitemallMechanismGoodsVo goods = mechanismGoodsService.showDetail(id);
        Map<String, Object> data = new HashMap();
        data.put("goods", goods);
        return ResponseUtil.ok(data);
    }

    /**
     * 购买代金券
     * @param body
     * @return
     * @throws Exception
     */
    @RequestMapping("/buy")
    public Object buy(@RequestBody String body) throws Exception{
        //解密
        DesNoViUtil tools = new DesNoViUtil();

        Integer goodsId = JacksonUtil.parseInteger(body, "goodsId");
        Integer mechanismId = JacksonUtil.parseInteger(body, "mechanismId");
        String username = JacksonUtil.parseString(body, "username");
        Short numbers = JacksonUtil.parseShort(body, "numbers");
        Integer unitPrice = JacksonUtil.parseInteger(body, "unitPrice");
        String mobile = JacksonUtil.parseString(body, "mobile");
        Integer orderIntegral = JacksonUtil.parseInteger(body, "orderIntegral");
        Integer actualIntegral = JacksonUtil.parseInteger(body, "actualIntegral");
        Integer userId = JacksonUtil.parseInteger(body, "userId");
        //判断支付密码是否正确
        String payPassword = tools.decode(JacksonUtil.parseString(body, "password"));
        LitemallUser user = userService.findById(userId);
        List<LitemallMechanismProduct> product = productService.queryByGid(goodsId);

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (payPassword != null && !encoder.matches(payPassword, user.getPayPassword())) {
            return ResponseUtil.fail(-3, "支付密码不对!");
        }
        if(user.getIntegral() < actualIntegral){
            return ResponseUtil.fail(-2, "积分余额不足");
        }
        if(product.get(0).getNumber() < numbers){
            return ResponseUtil.fail(-4, "库存不足");
        }

        // 开启事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            //订单信息插入voucherOrder表
            LitemallVoucherOrder voucherOrder = new LitemallVoucherOrder();
            voucherOrder.setUserId(userId);
            voucherOrder.setGoodsId(goodsId);
            voucherOrder.setMechanismId(mechanismId);
            voucherOrder.setConsignee(username);
            voucherOrder.setMobile(mobile);
            short number = 1;
            voucherOrder.setNumber(number);
            voucherOrder.setUnitPrice(unitPrice);
            voucherOrder.setOrderIntegral(unitPrice);
            voucherOrder.setActualIntegral(unitPrice);
            voucherOrder.setPayTime(LocalDateTime.now());
            voucherOrder.setReason("购买代金券");
            byte statu = 0;
            voucherOrder.setCommentsStatus(statu);
            voucherOrder.setStatus(statu);

            //循环插入voucherOrder表
            for(int i = 0; i < numbers; i++) {
                String orderSn = orderService.voucherOrderSn(userId); //订单号
                voucherOrder.setOrderSn(orderSn);
                litemallOrderVoucherService.add(voucherOrder);
            }

            //订单信息插入walletRecord表
            LitemallWalletRecord walletRecord = new LitemallWalletRecord();
            String orderSn = orderService.voucherOrderSn(userId); //订单号
            walletRecord.setUserId(userId);
            walletRecord.setMechaismId(mechanismId);
            byte type = 2;
            walletRecord.setType(type);
            walletRecord.setRecordSn(orderSn);
            walletRecord.setModifyReason("购买代金券");
            BigDecimal amount = new BigDecimal(0);
            walletRecord.setModifyAmount(amount);
            walletRecord.setModifyIntegral(-actualIntegral);
            walletRecord.setModifyResource(mechanismId);
            walletRecord.setModifyTime(LocalDateTime.now());
            byte payType = 3;
            walletRecord.setPayType(payType);
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");//设置日期格式
            String newsNo = LocalDateTime.now().format(fmt);
            walletRecord.setPayId(newsNo);
            walletRecord.setPayTime(LocalDateTime.now());

            walletRecordService.add(walletRecord);

            //减去库存
            LitemallMechanismProduct products = new LitemallMechanismProduct();
            products.setId(product.get(0).getId());
            Integer num = product.get(0).getNumber() - numbers;
            products.setNumber(num);
            productService.update(products);

            //扣除用户积分
            LitemallUser users = new LitemallUser();
            Integer integrals = user.getIntegral() - actualIntegral;
            users.setId(userId);
            users.setIntegral(integrals);
            userService.update(users);

            //扣除的积分加入机构法人账户
            LitemallMechanism mechanism = mechanismService.findById(mechanismId);
            LitemallUser litemallUser = userService.findByMobile(mechanism.getTelephone());
            //若法人不存在则自动添加进user
            if(litemallUser == null){
                LitemallUser u = new LitemallUser();
                u.setUsername(mechanism.getLegalPerson());
                byte gender = 0;
                u.setGender(gender);
                u.setUserLevel(gender);
                u.setMobile(mechanism.getTelephone());
                BigDecimal balance = new BigDecimal(0);
                u.setBalance(balance);
                u.setIntegral(actualIntegral);
                u.setFirstMechanism(mechanismId);
                byte sta = 0;
                u.setStatus(sta);
                u.setAddTime(LocalDateTime.now());
                userService.add(u);
            }else {
                if (litemallUser.getIntegral() == null) {
                    litemallUser.setIntegral(0);
                }
                litemallUser.setIntegral(litemallUser.getIntegral() + actualIntegral);
                userService.update(litemallUser);
            }
        } catch (Exception ex) {
            txManager.rollback(status);
            return ResponseUtil.fail(403, "网络延迟，请重新购买");
        }

        txManager.commit(status);
        return ResponseUtil.ok();
    }
}
